<template>
  <div class="pca-scatter-chart">
      <div class="chart-title">
      <span class="title-text">{{ title }}</span>
      <el-button
        class="export-btn"
        size="mini"
        @click="exportChartImage"
      >
        导出图片
      </el-button>
      </div>
    <div ref="chartContainer" class="chart-container"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'PcaScatterChart',
  props: {
    title: {
      type: String,
      default: 'PCA Score Plot'
    },
    scoreScatterPc1: {
      type: Array,
      required: true,
      default: () => []
    },
    scoreScatterPc2: {
      type: Array,
      required: true,
      default: () => []
    },
    pc1Value: {
      type: Number,
      required: true,
      default: 0
    },
    pc2Value: {
      type: Number,
      required: true,
      default: 0
    },
    ellipseAngle: { type: Number, default: 0 },
    ellipseWidth: { type: Number, default: 0 },
    ellipseHeight: { type: Number, default: 0 },
    width: { type: String, default: '100%' },
    height: { type: String, default: '400px' }
  },
  data() {
    return {
      chart: null
    };
  },
  computed: {
    chartData() {
      if (!this.scoreScatterPc1 || !this.scoreScatterPc2) return [];
      return this.scoreScatterPc1.map((pc1, index) => [
        pc1,
        this.scoreScatterPc2[index] || 0
      ]);
    },
    xAxisLabel() {
      return `PC1(${this.pc1Value.toFixed(1)}%)`;
    },
    yAxisLabel() {
      return `PC2(${this.pc2Value.toFixed(1)}%)`;
    }
  },
  mounted() {
    this.initChart();
    window.addEventListener('resize', this.handleResize);
  },
  beforeDestroy() {
    if (this.chart) this.chart.dispose();
    window.removeEventListener('resize', this.handleResize);
  },
  watch: {
    chartData: { handler() { this.updateChart(); }, deep: true },
    pc1Value() { this.updateChart(); },
    pc2Value() { this.updateChart(); },
    ellipseAngle() { this.updateChart(); },
    ellipseWidth() { this.updateChart(); },
    ellipseHeight() { this.updateChart(); }
  },
  methods: {
    initChart() {
      if (!this.$refs.chartContainer) return;
      this.chart = echarts.init(this.$refs.chartContainer);
      this.updateChart();
    },

    generateEllipseData() {
      if (!this.ellipseWidth || !this.ellipseHeight) return [];
      const points = [];
      const numPoints = 100;
      const a = this.ellipseWidth / 2;
      const b = this.ellipseHeight / 2;
      const angleRad = (this.ellipseAngle * Math.PI) / 180;
      for (let i = 0; i <= numPoints; i++) {
        const t = (2 * Math.PI * i) / numPoints;
        const x = a * Math.cos(t);
        const y = b * Math.sin(t);
        const rotatedX = x * Math.cos(angleRad) - y * Math.sin(angleRad);
        const rotatedY = x * Math.sin(angleRad) + y * Math.cos(angleRad);
        points.push([rotatedX, rotatedY]);
      }
      return points;
    },

    updateChart() {
      if (!this.chart) return;
      const option = {
        backgroundColor: '#fff',
        grid: { left: '10%', right: '8%', bottom: '20%', top: '5%', containLabel: true },
        xAxis: {
          type: 'value',
          name: this.xAxisLabel,
          nameLocation: 'middle',
          nameGap: 30,
          nameTextStyle: { fontSize: 14, fontWeight: 'bold' }
        },
        yAxis: {
          type: 'value',
          name: this.yAxisLabel,
          nameLocation: 'middle',
          nameGap: 50,
          nameTextStyle: { fontSize: 14, fontWeight: 'bold' }
        },
        series: [
          {
            name: 'PCA Scores',
            type: 'scatter',
            data: this.chartData,
            symbolSize: 8,
            itemStyle: { color: '#4A90E2' }
          },
          {
            name: '95%置信椭圆',
            type: 'line',
            data: this.generateEllipseData(),
            showSymbol: false,
            lineStyle: { color: '#FF4444', width: 2 }
          }
        ],
        tooltip: {
          trigger: 'item',
          formatter: params => {
            const [pc1, pc2] = params.data;
            return `
              <div style="padding: 8px;">
                <div><strong>Sample ${params.dataIndex + 1}</strong></div>
                <div>PC1: ${pc1.toFixed(3)}</div>
                <div>PC2: ${pc2.toFixed(3)}</div>
              </div>
            `;
          }
        }
      };
      this.chart.setOption(option, true);
    },

    exportChartImage() {
      if (!this.chart) return;
      const img = this.chart.getDataURL({
        type: 'png',
        pixelRatio: 2,
        backgroundColor: '#fff'
      });
      const link = document.createElement('a');
      link.href = img;
      link.download = `${this.title || 'chart'}.png`;
      link.click();
    },

    handleResize() {
      if (this.chart) this.chart.resize();
    }
  }
};
</script>

<style scoped>
.pca-scatter-chart {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.chart-title {
  position: relative;
  text-align: center;
  font-size: 16px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  padding: 0 10px;
}

.title-text {
  display: inline-block;
  padding: 0 40px; /* 给右边按钮留空间 */
}

.chart-container {
  flex: 1;
  min-height: 300px;
  width: 100%;
}
.export-btn {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  padding: 2px 8px;
  background-color: #409eff;
  border: none;
  border-radius: 4px;
  color: #fff;
  cursor: pointer;
}
.export-btn:hover {
  background-color: #66b1ff;
}
</style>
